#include "mem_hash.h"
#include <stdio.h>
#include <stdlib.h>

#define HASH_TABLE_LENGTH 1024


hash_element_t **table;



int hash_function(size_t id) {
     return id % HASH_TABLE_LENGTH;
}

void hash_create_table() {
     int i;
     table = (hash_element_t **)malloc(HASH_TABLE_LENGTH * sizeof(hash_element_t *));
     for (i = 0; i < HASH_TABLE_LENGTH; i++) table[i] = NULL;
}

void hash_add(size_t id, size_t sz) {
     int key = hash_function(id);
     hash_element_t *previous = NULL;
     hash_element_t *current = table[key];
     
     while (current != NULL) {
	  previous = current;
	  current = current->next;
     }
     current = (hash_element_t *)malloc(sizeof(hash_element_t));
     if (previous != NULL) previous->next = current;
     else table[key] = current;
     
     current->id = id;
     current->sz = sz;
     current->get_count = 0;
     current->mem_addr = NULL;
     current->swap_addr = -1;
     current->next = NULL;
}

hash_element_t *hash_find(size_t id) {
     int key = hash_function(id);
     hash_element_t *current = table[key];
     
     while (current != NULL) {
	  if (current->id == id) return current;
	  current = current->next;
     }
     return NULL;
}

int hash_delete(size_t id) {
     int key = hash_function(id);
     hash_element_t *current = table[key];
     hash_element_t *previous = NULL;
     
     while (current != NULL){
	  if (current->id == id) {
	       if (previous != NULL) previous->next = current->next;
	       else table[key] = NULL;
	       free(current);
	       return 1;
	  }
	  previous = current;
	  current = current->next;
     }
     return 0;
}

void hash_remove_table() {
     int i;
     for (i = 0; i < HASH_TABLE_LENGTH; i++) {
	  hash_element_t *current = table[i];
	  hash_element_t *next;
	  
	  while (current != NULL) {
	       next = current->next;
	       free(current);
	       current = next;
	  }
     }
     free(table);
}
